//historic files that can copy permissions out from FS

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Security.AccessControl;
using System.Windows.Forms;
using GSPMigratorCore.GSPInterface;
using Microsoft.SharePoint;
using WinApp.Common;

namespace WinApp
{
    public partial class Form1 : BaseForm
    {
        public Form1()
        {
            InitializeComponent();
        }
        static StreamWriter writer;
        FileStream theFile;
        static int stoplevel = 3;
        GSPInterface intf = new GSPInterface();
        DateTime startDate = DateTime.Now;
        string fileName = string.Empty;
        string ext = string.Empty;

        private void btMigrate_Click(object sender, EventArgs e)
        {
            string logFile = "Log_{0:yyMMdd}.txt";
            logFile = ParseLogFilename(logFile);
            string path = Path.GetDirectoryName(logFile);
            fileName = Path.Combine(path, Path.GetFileNameWithoutExtension(logFile));
            ext = Path.GetExtension(logFile);

            stoplevel = int.Parse(tbLevel.Text.Trim());

            try
            {
                theFile = File.Open(fileName + ext, FileMode.OpenOrCreate, FileAccess.Write);
                try
                {
                    writer = new StreamWriter(theFile);
                    string rootDirPath = tbRootDirectory.Text;
                    
                    DirectoryInfo dir = new DirectoryInfo(rootDirPath);
                    DirectorySecurity ds = new DirectorySecurity(rootDirPath, AccessControlSections.All);

                    writer.WriteLine("DIR: {0}", rootDirPath);
                    ShowDirectory(0, rootDirPath);
                }
                catch (Exception eee)
                {                    
                    this.lbMsg.Text = eee.ToString();
                    writer.WriteLine(this.lbMsg.Text);
                }
                finally
                {
                    writer.Close();
                }               
            }
            catch (Exception ee)
            {
                this.lbMsg.Text = ee.ToString();
                writer.WriteLine(this.lbMsg.Text);
            }
            finally
            {               
                theFile.Close();
            }
            Console.ReadLine();
            lbMsg.Text = "Complete extracting ACL!";
            bgWorker.RunWorkerAsync(this.cBoxDocLib.Text + "|" + this.tbSPUrl.Text + "|" + this.cBoxReplace.Text);
        }
        
        /// <summary>
        /// Get all SharePoint document libraries in specified URL
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGetAllSPDocLib_Click(object sender, EventArgs e)
        {
            cBoxDocLib.Items.Clear();
            using (SPSite oSite = new SPSite(this.tbSPUrl.Text))
            {
                using (SPWeb oWeb = oSite.OpenWeb())
                {
                    SPListCollection oListColl = oWeb.GetListsOfType(SPBaseType.DocumentLibrary);
                   
                    foreach (SPList oList in oListColl)
                    {
                        cBoxDocLib.Items.Add(oList.Title);
                    }
                }
            }
            if (cBoxDocLib.Items.Count != 0)
            {
                cBoxDocLib.SelectedIndex = 0;
            }
        }

        #region File system test methods
        
        private void btnTestFS_Click(object sender, EventArgs e)
        {
            TestFS();
        }

        internal bool TestFS()
        {
            bool success = false;
            try
            {
                DirectorySecurity ds = new DirectorySecurity(tbRootDirectory.Text.Trim(), AccessControlSections.All);
                AuthorizationRuleCollection arc = ds.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
                success = true;
                this.lbMsg.Text = "File system connection OK!";
            }
            catch (Exception ex)
            {
                success = false;
                this.lbMsg.Text = "File system connection Failed! Details: " + System.Environment.NewLine + ex.ToString();
            }
            return success;
        }
        
        #endregion

        #region SharePoint test methods

        private void btnTestSP_Click(object sender, EventArgs e)
        {
            TestSharePoint();
        }

        internal bool TestSharePoint()
        {
            bool success = false;
            if (string.IsNullOrEmpty(this.tbSPAccount.Text))
            {
                this.lbMsg.Text = "Enter sp account";
                return success;
            }

            SPSecurity.RunWithElevatedPrivileges(delegate(){
                using (SPSite oSite = new SPSite(this.tbSPUrl.Text))
                {
                    using (SPWeb oWeb = oSite.OpenWeb())
                    {
                        SPUser oUser = oWeb.AllUsers[this.tbDomain.Text + @"\" + this.tbSPAccount.Text];
                        SPListCollection oListColl = oWeb.GetListsOfType(SPBaseType.DocumentLibrary);
                        List<string> docNames = new List<string>();

                        SPList oDocLib = oListColl[this.cBoxDocLib.Text];
                        if (oDocLib.DoesUserHavePermissions(oUser, SPBasePermissions.FullMask))
                        {
                            this.lbMsg.Text = string.Format("Account: {0} has permission to {1}", this.tbSPAccount.Text, this.cBoxDocLib.Text);
                        }
                        else
                        {
                            this.lbMsg.Text = string.Format("Account: {0} do not have permission to {1}", this.tbSPAccount.Text, this.cBoxDocLib.Text);
                        }
                    }
                }
            });
            
            
            return success;
        }

        #endregion

        #region utilities

        static string ParseLogFilename(string name)
        {
            return String.Format(name, DateTime.Now.Date);
        }

        #endregion

        private void ShowDirectory(int dirLevel, string dirPath)
        {
            bool spAdminAdded = false;
            DirectoryInfo dir = new DirectoryInfo(dirPath);
            dirLevel++;
            try
            {
                DirectorySecurity ds = new DirectorySecurity(dirPath, AccessControlSections.All);
                AuthorizationRuleCollection arc = ds.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
                foreach (FileSystemAccessRule ar in arc)
                {
                    try
                    {
                        string temp = string.Empty;
                            temp = ar.IdentityReference.Translate(typeof(System.Security.Principal.NTAccount)) + ": " + ar.AccessControlType + " " + ar.FileSystemRights;

                            if (temp.StartsWith(this.tbDomain.Text, StringComparison.OrdinalIgnoreCase))
                            {
                                writer.WriteLine(temp);
                            }
                            else if(!spAdminAdded) //no need keep repeating the system account permissions
                            { 
                                writer.WriteLine(this.tbDomain.Text + @"\" + this.tbSPAccount.Text + ": " + ar.AccessControlType + " " + ar.FileSystemRights);
                                spAdminAdded = true;
                            }
                    }
                    catch (System.Security.Principal.IdentityNotMappedException e)
                    {
                        //TODO: use system account of MOSS
                        if (!spAdminAdded)
                        {
                            if (this.cbException.Checked)
                            {
                                writer.WriteLine(this.tbDomain.Text + @"\" + this.tbSPAccount.Text + ": " + ar.AccessControlType + " " + ar.FileSystemRights);
                                spAdminAdded = true;
                            }
                        }
                    }
                }

            }
            catch (Exception e)
            {
                this.lbMsg.Text = e.ToString();
                writer.WriteLine(this.lbMsg.Text);
            }

            if (dirLevel >= stoplevel) return;

            if (cbEnumerateFiles.Checked)
            {
                // Show Each File
                foreach (FileInfo file in dir.GetFiles())
                {
                    string temp = string.Format("F: {0}", dirPath + "\\" + file.Name);
                    writer.WriteLine(temp);
                }
            }

            // Go through sub-directories
            // recursively
            foreach (DirectoryInfo subDir in dir.GetDirectories())
            {
                string x = string.Format("DIR: {0}", dirPath + @"\" + subDir.Name);

                writer.WriteLine();
                writer.WriteLine(x);
                ShowDirectory(dirLevel, dirPath + @"\" + subDir.Name);
            }
        }

        private void btnMigrate_Click(object sender, EventArgs e)
        {
            bgWorker.RunWorkerAsync();
            this.toolStripProgressBar1.Visible = true;
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                WriteLog(LogLevel.Debug, "Entered button click event handler");
                bool success = false;
                string input;
                string errMsg;
                using (StreamReader inStream = new StreamReader(fileName+ext))
                {
                    WriteLog(LogLevel.Debug, "Begin read file");
                    input = inStream.ReadToEnd();
                    WriteLog(LogLevel.Debug, "End read file");
                }
                if (intf.ValidateData(input, out errMsg))
                {
                    WriteLog(LogLevel.Debug, "Begin process data");
                    string[] temp = e.Argument.ToString().Split('|');
                    int lineFailed = -1; //not working yet
                    success = intf.ProcessData(temp[0], temp[1], input, temp[2], bgWorker, out lineFailed); //call
                    WriteLog(LogLevel.Debug, "End process data");
                    WriteLog(LogLevel.Error, "Failed at line: " + lineFailed);

                }
                else
                {
                    MessageBox.Show(errMsg);
                }

                if (success)
                {
                    WriteLog(LogLevel.Info, "Migration successfully completed");
                    MessageBox.Show("Folder creation & permissions assignment complete");
                }
            }
            catch (Exception ex)
            {
                ExceptionLog(ex);
                MessageBox.Show(string.Format("An unexpected error has occured, details: {0}", ex.Message));
            }
        }

        private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.toolStripProgressBar1.Value = e.ProgressPercentage;
            this.toolStripStatusLabel1.Text = e.ProgressPercentage + "%";
        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            toolStripProgressBar1.Value = 0;
            toolStripStatusLabel1.Text = "";
            toolStripStatusLabel.Text = "";
            this.toolStripProgressBar1.Visible = false;
        }
    }
}